<?php

declare(strict_types=1);

namespace App\CustHub\Service;

use App\CustHub\Constants\RoomTaskCenterTypeConstants;
use App\CustHub\Constants\TagModuleConstants;
use App\CustHub\Dto\RoomTcContentDto;
use App\CustHub\Helpers\BcMath;
use App\CustHub\Mapper\ChRoomTagMapper;
use App\CustHub\Mapper\ChSmartTagMapper;
use App\CustHub\Model\ChRoomAutoTagConfig;
use Hyperf\Di\Annotation\Inject;
use Mine\Abstracts\AbstractService;
use Mine\Annotation\Transaction;
use Mine\Exception\NormalStatusException;
use Mine\MineModel;
use function Hyperf\Collection\collect;
use function Hyperf\Collection\data_get;

/**
 * 智能标签
 */
class ChRoomTagService extends AbstractService
{
    public $mapper;

    #[Inject]
    protected ChRoomTaskCenterService $roomTaskCenterService;

    public function __construct(ChRoomTagMapper $mapper)
    {
        $this->mapper = $mapper;

    }

    /**
     * 群标签列表
     * @param array $params
     * @return array
     */
    public function tagList(array $params): array
    {
        $keyword = data_get($params,'keyword','');

        $list = $this->mapper->model::query()
            ->select(['id','name'])
            ->with(['tags'=>function ($query) use ($keyword) {
                $query->select(['id','name','parent_id','number'])->when(function ($query) use ($keyword){
                    $query->where('name','like',"%{$keyword}%");
                });
            }])
            ->where('main_uid',$params['main_uid'])
            ->where('parent_id',0)
            ->when(!empty($keyword),function ($query) use ($keyword){
                $query->where(function ($query) use ($keyword){
                    $query->where('name','like',"%{$keyword}%")
                        ->orWhereHas('tags',function ($query) use ($keyword){
                            $query->where('name','like',"%{$keyword}%");
                        });
                });
            })->get()->toArray();


        foreach ($list as $k=>$item){
            $list[$k]['slots'] = [
                'icon' => 'iconFolder'
            ];

            if(!empty($keyword) && empty($item['tags'])){
                $item['tags'] = $this->mapper->model::query()
                    ->select(['id','name','parent_id','number'])
                    ->where('parent_id',$item['id'])
                    ->get()->toArray();
            }

            $tags = $item['tags'];
            foreach ($tags as $tk => $tag){
                $tags[$tk]['slots'] = [
                    'icon' => 'iconDotdotGrey'
                ];
            }
            $list[$k]['tags'] = $tags;
        }

        return $list;
    }

    /**
     * 标签分页接口
     * @param array $params
     * @return array
     */
    public function tagPageList(array $params): array
    {
        $pageSize = $params['page_size'] ?? MineModel::PAGE_SIZE;
        $keyword = data_get($params,'keyword','');

        $list = $this->mapper->model::query()
            ->select(['id','name'])
            ->with(['tags'=>function ($query) {
                $query->select(['id','name','parent_id','number']);
            }])
            ->where('main_uid',$params['main_uid'])
            ->where('parent_id',0)
            ->when(!empty($keyword),function ($query) use ($keyword){
                $query->where($keyword,'like',"%{$keyword}%");
            })->paginate((int)$pageSize);
        return $this->mapper->setPaginate($list);
    }

    /**
     * 标签新增
     * @param array $data
     * @return mixed
     */
    #[Transaction]
    public function save(array $data): mixed
    {
        if($this->mapper->checkExistByName($data['main_uid'],$data['name'],0)){
            throw new NormalStatusException('分组名重复');
        }

        $parentId = $this->mapper->save($data);

        $tagCount = count($data['tags']);
        if($tagCount > 100){
            throw new NormalStatusException('标签数量已达上限');
        }

        $childData = $this->changeTagData($data['tags'],$data['uid'],$data['main_uid'],$parentId);
        $this->batchSave($childData);
        return $parentId;
    }

    /**
     * 标签修改
     * @param mixed $id
     * @param array $data
     * @return bool
     */
    public function update(mixed $id, array $data): bool
    {

        $info = $this->mapper->model::query()
            ->where('id',$id)
            ->where('main_uid',$data['main_uid'])
            ->first();
        if(empty($info)){
            throw new NormalStatusException('当前信息不存在');
        }

        $isGroup = $info->parent_id == 0;

        $parentId = $isGroup ? 0 : null;

        if($this->mapper->checkExistByName($data['main_uid'],$data['name'],$parentId,$id)){
            throw new NormalStatusException($isGroup ? '分组名重复' : '标签名称重复');
        }

        $info->name = $data['name'];
        $rst = $info->save();
        return $rst;
    }

    /**
     * 批量新增标签
     * @param array $data
     * @return bool
     */
    public function batchSaveTag(array $data): bool
    {
        $info = $this->mapper->model::query()
            ->where('id',$data['group_id'])
            ->where('main_uid',$data['main_uid'])
            ->first();
        if(empty($info) || $info->parent_id != 0){
            throw new NormalStatusException('请选择分组后新增标签');
        }

        $parentId = $data['group_id'];

        $tagCount = count($data['tags']);
        $beforeTagCount = $this->mapper->getCount($data['main_uid'],$parentId);
        if($tagCount + $beforeTagCount > 100){
            throw new NormalStatusException('标签数量已达上限');
        }

        $childData = $this->changeTagData($data['tags'],$data['uid'],$data['main_uid'],$parentId);
        return $this->batchSave($childData);
    }

    /**
     * 删除标签组
     * @param array $data
     * @return mixed
     * @throws \Exception
     */
    #[Transaction]
    public function deleteTagGroup(array $data): mixed
    {
        $info = $this->mapper->model::query()
            ->where('id',$data['id'])
            ->where('main_uid',$data['main_uid'])
            ->first();
        if(empty($info)){
            throw new NormalStatusException('删除失败');
        }

        $rst = $info->delete();
        if($rst){
            //删除自动打标签配置
            ChRoomAutoTagConfig::query()
                ->where('tag_id',$data['id'])
                ->delete();
            if($info->parent_id == 0){

                $childIds = $this->mapper->model::query()
                    ->where('parent_id',$data['id'])
                    ->pluck('id')->toArray();

                ChRoomAutoTagConfig::query()
                    ->whereIn('tag_id',$childIds)
                    ->delete();

                $this->mapper->model::query()
                    ->where('parent_id',$data['id'])
                    ->delete();
            }else{
                $count = $this->mapper->model::query()
                    ->where('parent_id',$info->parent_id)
                    ->count();
                if($count < 1){
                    $this->mapper->model::query()
                        ->where('id',$info->parent_id)
                        ->delete();
                }
            }
        }

        return $rst;
    }

    private function changeTagData(array $tags,mixed $uid,mixed $mainUid,mixed $parentId)
    {
        $childData = [];
        foreach ($tags as $k=>$item){
            if($this->mapper->checkExistByName($mainUid,$item)){
                throw new NormalStatusException('标签名称重复');
            }
            $childData[$k]['name'] = $item;
            $childData[$k]['uid'] = $uid;
            $childData[$k]['main_uid'] = $mainUid;
            $childData[$k]['parent_id'] = $parentId;
            $childData[$k]['sort'] = $k;
        }
        return $childData;
    }

    /**
     * 添加群标签关联
     * @param array $data
     * @return bool
     */
    public function addRoom(array $data): bool
    {
        $id = explode(',',$data['id']);
        $roomIds = json_decode($data['room_ids'],true);


        $content = new RoomTcContentDto();
        $content->setRoomIds($roomIds);
        $content->setTagIds($id);

        return $this->roomTaskCenterService->addTask($data['uid'],$data['main_uid'],RoomTaskCenterTypeConstants::TAG,$content);
    }

    /**
     * 标签里删除群
     * @param array $data
     * @return bool
     */
    public function delRoom(array $data): bool
    {
        $id = explode(',',$data['id']);
        $roomIds = json_decode($data['room_ids'],true);

        $content = new RoomTcContentDto();
        $content->setRoomIds($roomIds);
        $content->setRemoveTagIds($id);

        return $this->roomTaskCenterService->addTask($data['uid'],$data['main_uid'],RoomTaskCenterTypeConstants::REMOVE_TAG,$content);
    }

    /**
     * 移动客户
     * @param array $data
     * @return bool
     */
    public function moveRoom(array $data): bool
    {
        $id = $data['remove_id'];
        $moveTagIds = json_decode($data['move_tag_ids'],true);
        $roomIds = json_decode($data['room_ids'],true);

        $model = $this->mapper->findById($id);
        if(empty($model)){
            throw new NormalStatusException('移动失败');
        }

        $content = new RoomTcContentDto();
        $content->setRoomIds($roomIds);
        $content->setTagIds($moveTagIds);
        $content->setRemoveTagIds([$id]);

        return $this->roomTaskCenterService->addTask($data['uid'],$data['main_uid'],RoomTaskCenterTypeConstants::MOVE_TAG,$content);
    }

    public function getTagsByIds($ids)
    {
        return $this->mapper->getModel() ->  newQuery() -> whereIn('id',$ids) -> pluck('name');
    }

}